#include "medialist.h"
#include <QContextMenuEvent>
#include <QFileDialog>
#include "globalresource.h"

MediaList::MediaList(QWidget *parent)
    : QListWidget(parent),
    m_stMenu(this),
    m_stActAddFile(this),
    m_stActAddUrl(this),
    m_stActRemove(this),
    m_stActClearList(this)
{
#ifdef  Debug_Falg
    qDebug() << "The name is : <" << __func__ << "> The file is :<" << __FILE__ << ">Thread is <" << QThread::currentThreadId();
#endif
    setStyleSheet("background: transparent;");
    m_stMenu.setStyleSheet("QMenu { background-color: #87CEEB; color: white; }");
}

MediaList::~MediaList()
{
}

bool MediaList::Init()
{
#ifdef  Debug_Falg
    qDebug() << "The name is : <" << __func__ << "> The file is :<" << __FILE__ << ">Thread is <" << QThread::currentThreadId();
#endif
    // 设置 "添加文件" 动作的显示文本
    m_stActAddFile.setText("添加文件");
    // 将 "添加文件" 动作添加到右键菜单中
    m_stMenu.addAction(&m_stActAddFile);

    // 设置 "添加地址" 动作的显示文本
    m_stActAddUrl.setText("添加地址");
    // 将 "添加地址" 动作添加到右键菜单中
    m_stMenu.addAction(&m_stActAddUrl);

    // 设置 "移除" 动作的显示文本
    m_stActRemove.setText("移除");
    // 将 "移除" 动作添加到右键菜单中
    m_stMenu.addAction(&m_stActRemove);

    // 设置 "清空列表" 动作的显示文本
    m_stActClearList.setText("清空列表");
    // 将 "清空列表" 动作添加到右键菜单中
    m_stMenu.addAction(&m_stActClearList);

    // 将 "添加文件" 动作的触发信号连接到 AddFile 槽函数
    connect(&m_stActAddFile, &QAction::triggered, this, &MediaList::AddFile);
    // 将 "添加地址" 动作的触发信号连接到 AddUrl 槽函数
    connect(&m_stActAddUrl, &QAction::triggered, this, &MediaList::AddUrl);
    // 将 "移除" 动作的触发信号连接到 RemoveFile 槽函数
    connect(&m_stActRemove, &QAction::triggered, this, &MediaList::RemoveFile);
    // 将 "清空列表" 动作的触发信号连接到 QListWidget 的 clear 槽函数
    connect(&m_stActClearList, &QAction::triggered, this, &QListWidget::clear);

    return true;
}

/**
 * @brief 处理 MediaList 控件的右键菜单事件
 * 当用户在 MediaList 控件上点击鼠标右键时，该函数会被自动调用。
 * 它会在鼠标点击的全局位置显示之前初始化好的右键菜单，
 * 让用户能够选择菜单中的各项操作，如添加文件、添加地址等。
 *
 * @param event 指向 QContextMenuEvent 对象的指针，包含了右键菜单事件的相关信息，
 *              例如鼠标点击的全局位置。
 */
void MediaList::contextMenuEvent(QContextMenuEvent* event)
{
#ifdef  Debug_Falg
    qDebug() << "The name is : <" << __func__ << "> The file is :<" << __FILE__ << ">Thread is <" << QThread::currentThreadId();
#endif
    // 在鼠标点击的全局位置显示右键菜单，允许用户进行操作
    m_stMenu.exec(event->globalPos());
}

/**
 * @brief 处理添加文件的操作
 * 该函数会弹出一个文件选择对话框，允许用户选择多个视频文件。
 * 当用户选择文件后，会遍历所选文件列表，并发出 SigAddFile 信号，将每个文件的路径传递出去。
 */
void MediaList::AddFile()
{
#ifdef  Debug_Falg
    qDebug() << "The name is : <" << __func__ << "> The file is :<" << __FILE__ << ">Thread is <" << QThread::currentThreadId();
#endif
    QStringList listFileName = QFileDialog::getOpenFileNames(this, "打开文件", QDir::homePath(),
            "视频文件(*.mkv *.rmvb *.mp4 *.avi *.flv *.wmv *.3gp)");
    // 遍历用户选择的文件列表
    for (QString strFileName : listFileName)
    {
        // 发出 SigAddFile 信号，将选中文件的路径传递出去，以便其他模块处理
        emit SigAddFile(strFileName);
    }
}

/**
 * @brief 处理添加网络地址的操作
 * 该函数会弹出一个自定义的 URL 输入对话框，让用户输入网络地址。
 * 根据用户在对话框中的操作结果，决定是否发出添加文件的信号。
 */
void MediaList::AddUrl()
{
#ifdef  Debug_Falg
    qDebug() << "The name is : <" << __func__ << "> The file is :<" << __FILE__ << ">Thread is <" << QThread::currentThreadId();
#endif
    // 创建一个 UrlDialog 对话框实例，将当前 MediaList 控件作为其父窗口
    UrlDialog urlDialog(this);
    // 以模态方式显示对话框，并获取用户的操作结果
    int nResult = urlDialog.exec();
    // 检查用户是否点击了对话框的确定按钮
    if(nResult == QDialog::Accepted) {
        // 从对话框中获取用户输入的网络地址
        QString url = urlDialog.GetUrl();
        // 输出调试信息，表明成功获取到用户输入的网络地址
        qDebug() << "Add url ok, url: " << url;
        // 检查获取到的网络地址是否为空
        if(!url.isEmpty()) {
            // 输出调试信息，表明准备发出添加文件的信号
            qDebug() << "SigAddFile url: " << url;
            // 发出 SigAddFile 信号，将用户输入的网络地址传递出去，以便其他模块处理
            emit SigAddFile(url);
        }
    } else {
        // 输出调试信息，表明用户取消了添加网络地址的操作
        qDebug() << "Add url no";
    }
}

/**
 * @brief 从媒体列表中移除当前选中的文件项
 *
 * 该函数会获取当前在 MediaList 控件中选中行的索引，
 * 并使用 `takeItem` 方法将该行对应的列表项从列表中移除。
 * 移除后，该列表项的所有权将被转移，Qt 不会自动管理其内存，
 * 若该列表项有动态分配的资源，需要在外部进行内存管理。
 */
void MediaList::RemoveFile()
{
#ifdef  Debug_Falg
    qDebug() << "The name is : <" << __func__ << "> The file is :<" << __FILE__ << ">Thread is <" << QThread::currentThreadId();
#endif
    // 获取当前选中行的列表项并从列表中移除
    takeItem(currentRow());
}

void MediaList::clearList()
{
    this->clear();
}

